package com.hotel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotel.entity.SysUser;
import com.hotel.mapper.SysUserMapper;
import com.hotel.service.SysUserService;
import com.hotel.dto.LoginRequest;
import com.hotel.dto.LoginResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;

/**
 * 系统用户服务实现类
 * 
 * @author Hotel Management Team
 */
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final PasswordEncoder passwordEncoder;
    private final SecretKey jwtSecretKey = Keys.secretKeyFor(SignatureAlgorithm.HS512); //密钥
    private final long jwtExpirationMs = 86400000; // 24 hours
    private final long active = 1; // 24 hours

    @Override
    public LoginResponse login(LoginRequest request) {
        // 根据用户名查询用户
        SysUser user = getUserByUsername(request.getUsername());
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 检查用户状态
        if (!"active".equals(user.getStatus())) {
            throw new RuntimeException("用户已被禁用");
        }

        // 更新最后登录时间
        updateLastLoginTime(user.getId());

        // 生成Token
        String token = generateToken(user);

        // 构建用户信息
        LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo();
        userInfo.setId(user.getId());
        userInfo.setUsername(user.getUsername());
        userInfo.setRealName(user.getRealName());
        userInfo.setEmail(user.getEmail());
        userInfo.setPhone(user.getPhone());
        userInfo.setAvatar(user.getPassword());
        userInfo.setStatus(user.getStatus());
        //userInfo.setLastLoginTime(user.get());

        // 构建登录响应
        LoginResponse response = new LoginResponse(token, userInfo);
        response.setExpiresIn(7200L); // 2小时
        response.setExpiresAt(LocalDateTime.now().plusHours(2));
        response.setPermissions(getUserPermissions(user.getId()));
        response.setRoles(getUserRoles(user.getId()));

        return response;
    }

    @Override
    public void logout(String token) {
        // 这里可以实现token黑名单机制
        // 暂时简单处理
    }

    @Override
    public SysUser getCurrentUser(String token) {
        Long userId = validateToken(token);
        if (userId == null) {
            throw new RuntimeException("无效的token");
        }
        return getById(userId);
    }

    @Override
    public void createUser(SysUser user) {
        // 检查用户名是否已存在
        if (existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (StringUtils.hasText(user.getEmail()) && existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }

        // 检查手机号是否已存在
        if (StringUtils.hasText(user.getPhone()) && existsByPhone(user.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 加密密码
        if (StringUtils.hasText(user.getPassword())) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        } else {
            // 设置默认密码
            user.setPassword(passwordEncoder.encode("123456"));
        }

        // 设置默认状态
        if (user.getStatus() == null) {
            user.setStatus(1);
        }

        save(user);
    }

    @Override
    public void updateUser(SysUser user) {
        SysUser existingUser = getById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查用户名是否被其他用户使用
        if (!existingUser.getUsername().equals(user.getUsername()) && existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查邮箱是否被其他用户使用
        if (StringUtils.hasText(user.getEmail()) && 
            !user.getEmail().equals(existingUser.getEmail()) && 
            existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }

        // 检查手机号是否被其他用户使用
        if (StringUtils.hasText(user.getPhone()) && 
            !user.getPhone().equals(existingUser.getPhone()) && 
            existsByPhone(user.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 不更新密码字段
        user.setPassword(null);
        updateById(user);
    }

    @Override
    public void deleteUser(Long id) {
        if (!removeById(id)) {
            throw new RuntimeException("删除用户失败");
        }
    }

    @Override
    public void resetPassword(Long id) {
        SysUser user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        user.setPassword(passwordEncoder.encode("123456"));
        updateById(user);
    }

    @Override
    public void changePassword(Long id, String oldPassword, String newPassword) {
        SysUser user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        updateById(user);
    }
@Override
public void changePassword(String token, String oldPassword, String newPassword) {
    Long id = validateToken(token);
    if (id == null) {
        throw new RuntimeException("无效的Token");
    }
    SysUser user = getById(id);
    if (user == null) {
        throw new RuntimeException("用户不存在");
    }

    if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
        throw new RuntimeException("原密码错误");
    }

    user.setPassword(passwordEncoder.encode(newPassword));
    updateById(user);
}

    @Override
    public void enableUser(Long id) {
        SysUser user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        user.setStatus(1); // "active" or 1 based on your SysUser entity
        updateById(user);
    }

    @Override
    public void disableUser(Long id) {
        SysUser user = getById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        user.setStatus(0); // "disabled" or 0 based on your SysUser entity
        updateById(user);
    }

    @Override
    public List<SysUser> getUserList(Integer page, Integer size, String keyword) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            queryWrapper.like("username", keyword)
                       .or()
                       .like("real_name", keyword)
                       .or()
                       .like("email", keyword)
                       .or()
                       .like("phone", keyword);
        }
        
        queryWrapper.orderByDesc("create_time");
        
        Page<SysUser> pageObj = new Page<>(page, size);
        Page<SysUser> result = page(pageObj, queryWrapper);
        
        return result.getRecords();
    }

    @Override
    public SysUser getUserByUsername(String username) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return getOne(queryWrapper);
    }

    @Override
    public boolean existsByUsername(String username) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return count(queryWrapper) > 0;
    }

    @Override
    public boolean existsByEmail(String email) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email);
        return count(queryWrapper) > 0;
    }

    @Override
    public boolean existsByPhone(String phone) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        return count(queryWrapper) > 0;
    }

    @Override
    public boolean validatePassword(String username, String password) {
        SysUser user = getUserByUsername(username);
        if (user == null) {
            return false;
        }
        return passwordEncoder.matches(password, user.getPassword());
    }

    @Override
    public void updateLastLoginTime(Long id) {
        SysUser user = getById(id);
        if (user != null) {
            //user.se(LocalDateTime.now());
            updateById(user);
        }
    }

    @Override
    public List<String> getUserPermissions(Long userId) {
        // 这里应该根据用户角色查询权限
        // 暂时返回默认权限
        List<String> permissions = new ArrayList<>();
        permissions.add("user:read");
        permissions.add("user:write");
        return permissions;
    }

    @Override
    public List<String> getUserRoles(Long userId) {
        // 这里应该查询用户角色关联表
        // 暂时返回默认角色
        List<String> roles = new ArrayList<>();
        roles.add("admin");
        return roles;
    }

    @Override
    public String generateToken(SysUser user) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpirationMs);

        return Jwts.builder()
                .setSubject(Long.toString(user.getId()))
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(jwtSecretKey, SignatureAlgorithm.HS512)
                .compact();
    }

    @Override
    public Long validateToken(String token) {
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        } else {
            return null;
        }

        try {
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(jwtSecretKey)
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
            return Long.parseLong(claims.getSubject());
        } catch (Exception e) {
            // Token validation failed (expired, malformed, etc.)
            return null;
        }
    }

    @Override
    public String refreshToken(String token) {
        Long userId = validateToken(token);
        if (userId == null) {
            throw new RuntimeException("无效的或过期的token，请重新登录");
        }

        SysUser user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // Check if user is active
        if (!(user.getStatus() == 0)){
            throw new RuntimeException("用户已被禁用");
        }

        return generateToken(user);
    }
}